package cn.edu.njuit.web.server.servive.impl;

import cn.edu.njuit.web.server.servive.MovieInfoService;
import cn.edu.njuit.web.server.servive.dto.MovieInfo;
import com.alibaba.fastjson.util.TypeUtils;
import utils.JdbcUtil;
import utils.Page;
import utils.PageTool;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class MovieInfoServiceJdbcImpl implements MovieInfoService {

    /**
     * 分页获取全部影片信息
     * @param page 页码
     * @param size 页长
     * @return 分页的影片列表
     */
    @Override
    public Page getAllMovieInfo(Integer page, Integer size) {
        // 1.定义sql
        String sql = "select * from movie_info order by movie_id";
        // 2.使用PageTool执行sql语句获取分页对象Page
        PageTool pageTool = new PageTool();
        Page moviePage = pageTool.getSqlPageResult(sql, page, size);
        if (moviePage != null) {
            // 3.将Page中原始数据List<Map<String, Object>>转化为目标类型List<MovieInfo>
            List<MovieInfo> movieList = convertMovieInfo(moviePage.getOriginalData());
            // 4.将转化后的List<MovieInfo>写入Page类型的content中
            moviePage.setContent(movieList);
            // 5.将Page中的原始数据释放，设置为null
            moviePage.setOriginalData(null);
        }
        return moviePage;
    }

    /**
          * 根据关键字拆线呢影片列表
          * @param keywords 查询关键字
          * @param page 页码
          * @param size 页长
          * @return 符合关键字的影片列表
          */
    @Override
    public Page<MovieInfo> getMoviesByKeywords(String keywords, Integer page, Integer size) {
        // 1.定义sql
        String sql = "select * from movie_info where name like concat('%', ?, '%') order by movie_id";
        // 2.使用PageTool执行sql语句获取分页对象Page
        PageTool pageTool = new PageTool();
        Page moviePage = pageTool.getSqlPageResult(sql, page, size, keywords);
        if (moviePage != null) {
            // 3.将Page中原始数据List<Map<String, Object>>转化为目标类型List<MovieInfo>
            List<MovieInfo> movieList = convertMovieInfo(moviePage.getOriginalData());
            // 4.将转化后的List<MovieInfo>写入Page类型的content中
            moviePage.setContent(movieList);
            // 5.将Page中的原始数据释放，设置为null
            moviePage.setOriginalData(null);
        }
        return moviePage;
    }

    /**
          * 获取指定影片数据
          * @param movieId 影片编码
          * @return 影片数据对象
          */
    @Override
    public MovieInfo getMovieById(long movieId) {
        // 1.定义sql
        String sql = "select * from movie_info where movie_id =?";
        // 2.使用JdbcUtil工具执行sql，获得查询结果Map<String, Object>
        JdbcUtil jdbcUtil = new JdbcUtil();
        Map<String, Object> movieMap = jdbcUtil.getOne(sql, movieId);
        MovieInfo movieInfo = null;
        if (movieMap != null) {
            // 3.将Map<String, Object>转化为MovieInfo对象
            movieInfo = convertMovieInfo(movieMap);
        }
        // 4.返回MovieInfo对象
        return movieInfo;
    }

    /**
          * 发布一部影片
          * @param movieInfo 影片数据对象
          * @return 保存成功后的影片数据对象
          */
    @Override
    public MovieInfo publishMovieInfo(MovieInfo movieInfo) {
        // 1.定义sql
        String sql = "insert into movie_info(name, img, name_en, length, movie_year, movie_publish_date)" +
                " values(?, ?, ?, ?, ?, ?)";
        // 2.使用JdbcUtil工具执行sql，获得自动增长的id值
        JdbcUtil jdbcUtil = new JdbcUtil();
        Long result = jdbcUtil.execInsertAutoId(sql,
                movieInfo.getMovieName(),
                movieInfo.getMovieImage(),
                movieInfo.getMovieEnglishName(),
                movieInfo.getMovieLength(),
                movieInfo.getMovieYear(),
                movieInfo.getMoviePublishDate()
        );
        // 3.将自动增长id值赋值给movieId字段
        if (result > 0) {
            movieInfo.setMovieId(result);
        }
        // 4.返回带有MovieId值的MovieInfo对象
        return movieInfo;
    }

    /**
          * 修改影片信息
          * @param movieInfo 影片数据对象
          * @return 保存成功后的影片数据对象
          */
    @Override
    public MovieInfo modifyMovieInfo(MovieInfo movieInfo) {
                // 1.定义sql
        String sql = "update movie_info set name =? " +
                ", img =?" +
                ", name_en =?" +
                ", length =?" +
                ", movie_year =?" +
                ", movie_publish_date =?" +
                " where movie_id =?";

        // 2.使用JdbcUtil工具执行sql，得到更新受影响的行数
        JdbcUtil jdbcUtil = new JdbcUtil();
        Integer result = jdbcUtil.exec(sql,
                movieInfo.getMovieName(),
                movieInfo.getMovieImage(),
                movieInfo.getMovieEnglishName(),
                movieInfo.getMovieLength(),
                movieInfo.getMovieYear(),
                movieInfo.getMoviePublishDate(),
                movieInfo.getMovieId());
        // 3.受影响行数>0即保存成功，返回保存的数据对象
        if (result > 0) {
            return movieInfo;
        }
        // 4.受影响行数不>0返回null，表示保存失败
        return null;
    }

    /**
          * 删除影片信息
          * @param movieId 需要删除的影片编码
          * @return 操作成功与失败标记
          */
    @Override
    public Boolean deleteMovieInfo(Long movieId) {
                // 1.定义sql
        String sql = "delete from movie_info where movie_id =?";
        // 2.使用JdbcUtil工具执行sql，得到更新受影响的行数
        JdbcUtil jdbcUtil = new JdbcUtil();
        Integer result = jdbcUtil.exec(sql, movieId);
        // 3.受影响行数>0表示删除成功，反之则为失败
        return result > 0;
    }

    /**
          * 将SQL语句执行得到的Map<String, Object>数据转换为MovieInfo数据对象
          * @param movieMap
          * @return
          */
    private MovieInfo convertMovieInfo(Map movieMap) {
        MovieInfo movieInfo = new MovieInfo();
        movieInfo.setMovieId(TypeUtils.castToLong(movieMap.get("movie_id")));
        movieInfo.setMovieImage(TypeUtils.castToString(movieMap.get("img")));
        movieInfo.setMovieLength(TypeUtils.castToInt(movieMap.get("length")));
        movieInfo.setMovieName(TypeUtils.castToString(movieMap.get("name")));
        movieInfo.setMovieRating(TypeUtils.castToFloat(movieMap.get("rating")));
        movieInfo.setMovieYear(TypeUtils.castToString(movieMap.get("movie_year")));
        movieInfo.setMovieEnglishName(TypeUtils.castToString(movieMap.get("name_en")));
        movieInfo.setMoviePublishDate(TypeUtils.castToString(movieMap.get("movie_publish_date")));
        return  movieInfo;
    }

    /**
     * 将数据库获取的原始数据List<String, Object>数据转换为数据对象列表List<MovieInfo>
     * @param movieMapList
     * @return List<MovieInfo> 转化后的数据对象列表
     */
    private List<MovieInfo> convertMovieInfo(List<Map<String, Object>> movieMapList) {
        List<MovieInfo> resultList = new ArrayList<>();
        for (Map<String, Object> rowMap : movieMapList) {
            MovieInfo movieInfo = convertMovieInfo(rowMap);
            resultList.add(movieInfo);
        }
        return resultList;
    }


}
